package com.hyper_yang._05_juc.chap08;

import java.util.concurrent.*;

//处理任务类：
class MyRunnable implements Runnable {
    int number;

    public MyRunnable(int number) {
        this.number = number;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " MyRunnable ... " + number);
    }
}

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        try {
            System.out.println(Thread.currentThread().getName() + " MyCallable ... ");
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(Thread.currentThread().getName() + " MyCallable ... ");
        return 100;
    }
}

public class CustomizeThreadPoolDemo {
    public static void main(String[] args) {
        //如何设置线程池线程数量？
        int cpu = Runtime.getRuntime().availableProcessors(); //获取系统逻辑CPU核数  12

        // todo: CPU计算行任务(执行任务多，但时间短)     线程数量：CPU + 1   让CPU发挥最大性能。设置线程过多会导致CPU切换线程，损失性能。
        // todo: I/O密集型任务(执行任务多,但时间长)      线程数量：2 * CPU   让CPU调度多一些线程，执行更多的任务。让CPU忙起来。
        //创建自定义线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                //有时设置核心线程数和最大线程数一致。不用来回伸缩。即:不用总去销毁再创建。
                2,//cpu + 1, //核心线程数
                5,//2 * cpu,//最大线程数
                10, //空闲等待时间
                TimeUnit.MINUTES, //时间单位
                new ArrayBlockingQueue<>(10), //任务队列
                Executors.defaultThreadFactory(),//线程工厂,管理线程生命周期
                //new ThreadPoolExecutor.AbortPolicy() //最大饱和拒绝策略。直接抛异常。  java.util.concurrent.RejectedExecutionException
                //new ThreadPoolExecutor.CallerRunsPolicy() //交给调用者线程处理
                //new ThreadPoolExecutor.DiscardOldestPolicy() //丢弃最早等待的任务。
                //new ThreadPoolExecutor.DiscardPolicy() //丢弃刚来的任务
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        System.out.println(" 自定义最大饱和策略 ");
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        executor.execute(r); //重新交给线程池来处理
                    }
                }
        );


        int count = threadPoolExecutor.prestartAllCoreThreads();//线程池一旦被创建，那么，直接创建核心线程程数。
        System.out.println("count = " + count);

        for (int i = 1; i <= 13; i++) {
            try {
                threadPoolExecutor.execute(new MyRunnable(i)); //不用返回结果或异常
                //threadPoolExecutor.submit(new MyRunnable());
                //Future<Integer> future = threadPoolExecutor.submit(new MyCallable());//需要返回结果或异常

                //Integer result = future.get(); //一定获取结果，任务一定要完成。否则一直阻塞。
                //Integer result2 = future.get(10, TimeUnit.SECONDS); //获取任务结果只等待指定时间，时间到了任务还没完成，就不等了(任务取消)。

                //System.out.println("result2 = " + result2);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //threadPoolExecutor.shutdown(); //销毁线程池。
    }
}
